
package com.arcsoft.api.system.face;

import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CustomFaceEnginePool extends GenericObjectPool<AFaceEngine> {
    // 记录借出对象及其借出时间
    private final Map<AFaceEngine, Long> borrowedObjects = new ConcurrentHashMap<>();
    private static final long MAX_BORROW_TIME = 10000; // 最大借出时间 10s

    public CustomFaceEnginePool(PooledObjectFactory<AFaceEngine> factory, GenericObjectPoolConfig<AFaceEngine> config) {
        super(factory, config);
        // 启动监控线程
        new Thread(this::monitorBorrowedObjects).start();
    }

    @Override
    public AFaceEngine borrowObject() throws Exception {
        AFaceEngine engine = super.borrowObject();
        // 记录借出时间
        borrowedObjects.put(engine, System.currentTimeMillis());
        return engine;
    }

    @Override
    public void returnObject(AFaceEngine obj) {
        // 移除借出记录
        borrowedObjects.remove(obj);
        super.returnObject(obj);
    }

    /**
     * 阻塞等待核心对象归还
     */
    public AFaceEngine borrowCoreObject(long maxWaitMillis) throws Exception {
        AFaceEngine coreObject = null;
        long startTime = System.currentTimeMillis();
        while (System.currentTimeMillis() - startTime < maxWaitMillis) {
            coreObject = this.borrowObject();
            if (coreObject.isCore()) {
                borrowedObjects.put(coreObject, System.currentTimeMillis());
                return coreObject;
            } else {
                this.returnObject(coreObject);
            }
            Thread.sleep(100);
        }
        throw new Exception("Timed out waiting for core object.");
    }

    /**
     * 监控借出的对象，检测超时
     */
    private void monitorBorrowedObjects() {
        while (true) {
            try {
                Thread.sleep(1000); // 每秒扫描一次
                long currentTime = System.currentTimeMillis();
                for (Map.Entry<AFaceEngine, Long> entry : borrowedObjects.entrySet()) {
                    long borrowedTime = currentTime - entry.getValue();
                    if (borrowedTime > MAX_BORROW_TIME) {
                        // 超时强制归还
                        AFaceEngine engine = entry.getKey();
                        System.err.println("Engine timed out, forcing return: " + engine);
                        borrowedObjects.remove(engine); // 从记录中移除
                        super.returnObject(engine); // 强制归还到池中
                    }
                }
            } catch (Exception e) {
                System.err.println("Error in monitor thread: " + e.getMessage());
            }
        }
    }
}

